﻿using MP_Game.Protos.V1;
using System.Collections.Generic;
using System.Threading;

namespace MP_Network
{
    public class SessionMgr : Singleton<SessionMgr>
    {
        private int _instanceInter;
        private Dictionary<int, Session> _sessionDic = new();
        private Dictionary<CliType, Session> _clientDic = new();

        // 线程安全锁对象
        private readonly object _sessionLock = new object();
        private readonly object _clientLock = new object();
        /// <summary>
        /// 添加会话，设置会话的SessionId
        /// </summary>
        /// <param name="session"></param>
        /// <param name="sessionId"></param>
        public void AddSession(Session session, int sessionId = -1)
        {
            if (sessionId < 0)
            {
                sessionId = GetInstanceInter();
            }
            lock (_sessionLock)
            {
                if (!_sessionDic.ContainsKey(sessionId))
                {
                    session.SessionId = sessionId;
                    _sessionDic.Add(sessionId, session);
                }
            }
        }
        public void AddCli(CliType type, Session session)
        {
            if (!_clientDic.ContainsKey(type))
            {
                _clientDic.Add(type, session);
            }
            else if (_clientDic[type] == null)
            {
                _clientDic[type] = session;
                LogMsg.Warn($"SessionMgr::AddCli::{type}之前掉线了，现在重连成功！");
            }
            else
            {
                LogMsg.Warn($"SessionMgr::AddCli::重复的CliType正在被加入：{type}");
            }
        }

        /// <summary>
        /// 是否是玩家客户端的会话
        /// </summary>
        /// <param name="session"></param>
        /// <returns></returns>
        private bool IsPlayerClient(Session session)
        {
            return session._clientType == CliType.Player;
        }

        public void RemoveSession(int sessionId)
        {
            lock (_sessionLock)
            {
                if (_sessionDic.ContainsKey(sessionId))
                {
                    _sessionDic.Remove(sessionId);
                }
            }
        }

        public void RemoveClient(CliType type)
        {
            lock (_clientLock)
            {
                if (_clientDic.ContainsKey(type))
                {
                    _clientDic.Remove(type);
                }
            }
        }
        public Session? GetSession(int sessionId)
        {
            lock (_sessionLock)
            {
                if (_sessionDic.ContainsKey(sessionId))
                {
                    return _sessionDic[sessionId];
                }
            }
            return null;
        }

        public Session? GetClient(CliType type)
        {
            lock (_clientLock)
            {
                if (_clientDic.ContainsKey(type))
                {
                    return _clientDic[type];
                }
            }
            return null;
        }
        /// <summary>
        /// 得到所有客户端
        /// </summary>
        /// <returns></returns>
        public Dictionary<int, Session> GetSessions()
        {
            lock (_sessionLock)
            {
                // 返回副本以避免外部修改
                return new Dictionary<int, Session>(_sessionDic);
            }
        }

        /// <summary>
        /// 得到所有服务器客户端
        /// </summary>
        /// <returns></returns>
        public Dictionary<CliType, Session> GetClients()
        {
            lock (_clientLock)
            {
                // 返回副本以避免外部修改
                return new Dictionary<CliType, Session>(_clientDic);
            }
        }

        public int GetSessionCount()
        {
            lock (_sessionLock)
            {
                return _sessionDic.Count;
            }
        }
        public int GetInstanceInter()
        {
            return Interlocked.Increment(ref _instanceInter);
        }

        /// <summary>
        /// 安全地遍历所有会话（线程安全）
        /// </summary>
        /// <param name="action">对每个会话执行的操作</param>
        public void ForEachSession(System.Action<Session> action)
        {
            if (action == null) return;

            lock (_sessionLock)
            {
                foreach (var session in _sessionDic.Values)
                {
                    try
                    {
                        action(session);
                    }
                    catch (System.Exception ex)
                    {
                        LogMsg.Error($"遍历会话时发生错误: {ex.Message}");
                    }
                }
            }
        }

        /// <summary>
        /// 安全地遍历所有客户端（线程安全）
        /// </summary>
        /// <param name="action">对每个客户端执行的操作</param>
        public void ForEachClient(System.Action<Session> action)
        {
            if (action == null) return;

            lock (_clientLock)
            {
                foreach (var client in _clientDic.Values)
                {
                    try
                    {
                        action(client);
                    }
                    catch (System.Exception ex)
                    {
                        LogMsg.Error($"遍历客户端时发生错误: {ex.Message}");
                    }
                }
            }
        }

        /// <summary>
        /// 清理所有会话（线程安全）
        /// </summary>
        public void ClearAllSessions()
        {
            lock (_sessionLock)
            {
                _sessionDic.Clear();
            }
        }

        /// <summary>
        /// 清理所有客户端（线程安全）
        /// </summary>
        public void ClearAllClients()
        {
            lock (_clientLock)
            {
                _clientDic.Clear();
            }
        }
    }
}
